﻿using System;
using System.Collections.Generic;
using System.Web;
using BAL;
using System.Web.SessionState;
using Newtonsoft.Json;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;

namespace ProjectQuaDep.Ajax
{
    /// <summary>
    /// Summary description for UploadHanlder
    /// </summary>
    public class UploadHanlder : IHttpHandler, IRequiresSessionState
    {
        private string strImages = string.Empty;
        public string Image = "image";
        public string h = "h";
        public string w = "w";
        public string x = "x";
        public string y = "y";

        public void ProcessRequest(HttpContext context)
        {
            ResponseData responseData = new ResponseData();
            string command = string.Empty;
            if (context.Request.RequestType == "POST")
            {
                if (context.Request["command"] != null)
                {
                    command = context.Request["command"];
                }
                else
                {
                    command = null;
                    responseData = new ResponseData
                    {
                        Success = false,
                        Message = "Không có hành động này."
                    };
                }
            }
            else
            {
                if (context.Request.QueryString["command"] != null)
                {
                    command = context.Request.QueryString["command"];
                }
                else
                {
                    command = null;
                    responseData = new ResponseData
                    {
                        Success = false,
                        Message = "Không có hành động này."
                    };
                }
            }

            if (command != null)
            {

                switch (command.ToLower())
                {
                    case "uploadavatar":
                        responseData = UploadAvatar(context);
                        break;
                    case "cropavatar":
                        responseData = CropAvatar(context);
                        break;
                    case "multiuploadimages":
                        responseData = MultiUploadImages(context);
                        break;
                    default:
                        responseData = new ResponseData
                        {
                            Message = "Không có hành động này",
                            Success = false
                        };
                        break;
                }
            }       

            context.Response.ContentType = "text/plain";
            context.Response.Write(JsonConvert.SerializeObject(responseData, Formatting.Indented));
        }

        private ResponseData UploadAvatar(HttpContext context)
        {
            ResponseData responseData = new ResponseData();
            if (context.Request.Files.Count > 0)
            {
                //responseData = Upload(context, context.Request.Files[0], UploadUtils.AvatarUploadMaxSize,
                //                      UploadUtils.AvatarMaxWidth, UploadUtils.AvatarMaxHeight, true, 
                //                      UploadUtils.AvatarThumbWith, minWidth: UploadUtils.AvatarMinWidth, minHeight:UploadUtils.AvatarMinHeight);
                responseData = Upload(context, context.Request.Files[0], UploadUtils.ImagesUploadMaxSize, minWidth: UploadUtils.ImageMinWidth);
                responseData.Images = strImages.TrimEnd(',');
            }
            return responseData;
        }

        private ResponseData MultiUploadImages(HttpContext context)
        {
            var count = 0;
            var lstReponse = new List<ResponseData>();
            ResponseData responseData = new ResponseData();
            //if (count > UploadUtils.ImagesUploadMaxItems)
            //{
            //    responseData.Success = false;
            //    responseData.Message = String.Format("Bạn chỉ được upload tối đa {0} hình.",
            //                                         UploadUtils.ImagesUploadMaxItems - 1);
            //}
            //else 
            if (context.Request.Files.Count > (UploadUtils.ImagesUploadMaxItems - 1))
            {
                lstReponse.Add(new ResponseData
                {
                    Success = false,
                    Message =
                        String.Format("Bạn chỉ được upload tối đa {0} hình.",
                                      UploadUtils.ImagesUploadMaxItems - 1)
                });
            }
            else if (context.Request.Files.Count > 0)
            {
                var total = count > 0
                                ? ((context.Request.Files.Count > (UploadUtils.ImagesUploadMaxItems - count))
                                       ? (UploadUtils.ImagesUploadMaxItems - count)
                                       : context.Request.Files.Count)
                                : ((context.Request.Files.Count > (UploadUtils.ImagesUploadMaxItems - 1))
                                       ? (UploadUtils.ImagesUploadMaxItems - 1)
                                       : context.Request.Files.Count);

                for (int i = 0; i < total; i++)
                {
                    var responseItem = Upload(context, context.Request.Files[i], UploadUtils.ImagesUploadMaxSize, minWidth: UploadUtils.ImageMinWidth);
                    lstReponse.Add(responseItem);
                }
                responseData.Success = true;
                responseData.Images = strImages;
                responseData.Message = "Đã upload ảnh xong. Bạn hãy điền các thông tin liên lạc còn lại vào ô dưới đây và lick tham gia cuộc thi để hoàn thành việc tải ảnh tham gia cuộc thi";
            }
            else
            {
                responseData.Success = false;
                responseData.Message = "Bạn phải chọn một file để up ảnh!";
            }
            responseData.Data = lstReponse;
            responseData.Total = lstReponse.Count;
            return responseData;
        }

        private ResponseData Upload(HttpContext context, HttpPostedFile file,  long uploadMaxSize = 0, int maxWidth = 0, int maxHeight = 0, bool isThumb = false, int width = 0, int minWidth = 0, int minHeight = 0)
        {
            var responseData = new ResponseData();
            if (JpegHelper.HasJpegExtension(file.FileName))
            {
                if (uploadMaxSize == 0 || file.ContentLength <= uploadMaxSize)
                {
                    try
                    {
                        var extention = Path.GetExtension(file.FileName);
                        string path = context.Server.MapPath(UploadUtils.GenerateUserImagesFolder());
                        string pathThumb = context.Server.MapPath(UploadUtils.GenerateUserThumbImagesFolder());
                        if (!Directory.Exists(path))
                            Directory.CreateDirectory(path);

                        if (!Directory.Exists(pathThumb))
                            Directory.CreateDirectory(pathThumb);

                        string nameFileSave = UploadUtils.GenerateUserImagesFileName(extention);
                        path = path + nameFileSave;
                        pathThumb = pathThumb + UploadUtils.GenerateUserImagesFileName(extention);

                        var bdata = new byte[file.ContentLength];
                        file.InputStream.Read(bdata, 0, bdata.Length);
                        var ms = new MemoryStream(bdata);
                        var iImage = System.Drawing.Image.FromStream(ms);

                        //if (maxWidth > 0 && iImage.Width > maxWidth)
                        //{
                        //    responseData.Success = false;
                        //    responseData.Message = string.Format("Chiều rộng ảnh không quá {0} pixels!", maxWidth);
                        //    return responseData;
                        //}
                        //if (maxHeight > 0 && iImage.Height > maxHeight)
                        //{
                        //    responseData.Success = false;
                        //    responseData.Message = string.Format("Chiều cao ảnh không quá {0} pixels!", maxHeight);
                        //    return responseData;
                        //}
                        //if (minWidth > 0 && iImage.Width < minWidth)
                        //{
                        //    responseData.Success = false;
                        //    responseData.Message = string.Format("Chiều rộng ảnh không được nhỏ hơn {0} pixels!", minWidth);
                        //    return responseData;
                        //}
                        //if (minHeight > 0 && iImage.Height < minHeight)
                        //{
                        //    responseData.Success = false;
                        //    responseData.Message = string.Format("Chiều cao ảnh không được nhỏ hơn {0} pixels!", minHeight);
                        //    return responseData;
                        //}

                        var s = new StorageWrapper();
                        ms.Seek(0, SeekOrigin.Begin);
                        file.SaveAs(path.TrimStart('/'));
                        strImages += UploadUtils.GenerateUserImagesFolder() + nameFileSave + ",";

                        ////tạo 1 file ảnh thumb ảo
                        //var resizeImage = getResizedImage(path.TrimStart('/'),100  ,50);
                        //using (var msResize = new MemoryStream(resizeImage, 0, resizeImage.Length))
                        //{
                        //    msResize.Write(resizeImage, 0, resizeImage.Length);
                        //    msResize.Seek(0, SeekOrigin.Begin);
                        //    file.SaveAs(pathThumb.TrimStart('/'));
                        //}

                        responseData.Success = true;
                        responseData.Data = path;
                        responseData.ExSize = iImage.Width + "x" + iImage.Height;
                        responseData.Message = "Đã upload ảnh xong. Bạn hãy điền các thông tin liên lạc còn lại vào ô dưới đây và lick tham gia cuộc thi để hoàn thành việc tải ảnh tham gia cuộc thi";
                    }
                    catch (Exception ex)
                    {
                        responseData.Success = false;
                        responseData.Message = "Lỗi upload ảnh";
                    }
                }
                else
                {
                    responseData.Success = false;
                    responseData.Message = "Ảnh vượt quá dung lượng cho phép (Tối đa 5MB) !";
                }
            }
            else
            {
                responseData.Success = false;
                responseData.Message = "Ảnh phải là định dạng jpg hoặc png!";
            }
            return responseData;
        }

        private ResponseData CropAvatar(HttpContext context  )
        {
            var responseData = new ResponseData();

           
            var img = context.Request[Image];
            var w = (int)ConvertUtility.ConvertTo<float>(context.Request["w"]);
            var h = (int)ConvertUtility.ConvertTo<float>(context.Request["h"]);
            var x = (int)ConvertUtility.ConvertTo<float>(context.Request["x"]);
            var y = (int)ConvertUtility.ConvertTo<float>(context.Request["y"]);
            try
            {
                var cropImage = Crop(img, w, h, x, y);
                using (var ms = new MemoryStream(cropImage, 0, cropImage.Length))
                {
                    using (System.Drawing.Image CroppedImage = System.Drawing.Image.FromStream(ms, true))
                    {
                        string GenerateCropUserImagesFolder = UploadUtils.GenerateCropUserImagesFolder();
                        var path = HttpContext.Current.Request.PhysicalApplicationPath + GenerateCropUserImagesFolder;

                        if (!Directory.Exists(path))
                            Directory.CreateDirectory(path);

                        path = path + "crop_" + UploadUtils.CutImageName(img);
                        CroppedImage.Save(path.TrimStart('/'));
                        strImages = UploadUtils.GenerateUserImagesFolder() + "crop_" + UploadUtils.CutImageName(img);

                        responseData.Success = true;
                        responseData.Images = strImages;
                        responseData.Data = path;
                        responseData.Message = "Upload ảnh thành công!";
                    }
                    
                }
            }
            catch (Exception ex)
            {

                responseData.Success = false;
                responseData.Message = "Lỗi crop ảnh";
            }
            return responseData;
        }

        static byte[] getResizedImage(String path, int width, int height)
        {
            Bitmap imgIn = new Bitmap(path);
            double y = imgIn.Height;
            double x = imgIn.Width;

            double factor = 1;
            if (width > 0)
            {
                factor = width / x;
            }
            else if (height > 0)
            {
                factor = height / y;
            }
            System.IO.MemoryStream outStream = new System.IO.MemoryStream();
            Bitmap imgOut = new Bitmap((int)(x * factor), (int)(y * factor));

            // Set DPI of image (xDpi, yDpi)
            imgOut.SetResolution(72, 72);

            Graphics g = Graphics.FromImage(imgOut);
            g.Clear(Color.White);
            g.DrawImage(imgIn, new Rectangle(0, 0, (int)(factor * x), (int)(factor * y)),
              new Rectangle(0, 0, (int)x, (int)y), GraphicsUnit.Pixel);

            imgOut.Save(outStream, getImageFormat(path));
            return outStream.ToArray();
        }

        static string getContentType(String path)
        {
            switch (Path.GetExtension(path))
            {
                case ".bmp": return "Image/bmp";
                case ".gif": return "Image/gif";
                case ".jpg": return "Image/jpeg";
                case ".png": return "Image/png";
                default: break;
            }
            return "";
        }

        static ImageFormat getImageFormat(String path)
        {
            switch (Path.GetExtension(path))
            {
                case ".bmp": return ImageFormat.Bmp;
                case ".gif": return ImageFormat.Gif;
                case ".jpg": return ImageFormat.Jpeg;
                case ".png": return ImageFormat.Png;
                default: break;
            }
            return ImageFormat.Jpeg;
        }

        static byte[] Crop(string Img, int Width, int Height, int X, int Y)
        {
            try
            {
                using (var imageStream = new System.Net.WebClient().OpenRead(Img))
                {
                    using (var originalImage = System.Drawing.Image.FromStream(imageStream))
                    {
                        using (var bmp = new Bitmap(Width, Height))
                        {
                            bmp.SetResolution(originalImage.HorizontalResolution, originalImage.VerticalResolution);

                            using (var Graphic = Graphics.FromImage(bmp))
                            {
                                Graphic.SmoothingMode = SmoothingMode.AntiAlias;
                                Graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
                                Graphic.PixelOffsetMode = PixelOffsetMode.HighQuality;
                                Graphic.DrawImage(originalImage, new Rectangle(0, 0, Width, Height), X, Y, Width, Height, GraphicsUnit.Pixel);
                                var ms = new MemoryStream();
                                bmp.Save(ms, originalImage.RawFormat);
                                return ms.GetBuffer();
                            }
                        }
                    }
                }
            }

            catch (Exception Ex)
            {
                throw (Ex);
            }

        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}